# -*- coding: utf-8 -*-

"""
@File: utils/FileOperation.py
@Time: 2024/8/29 10:20
@Author: TangZuChao
@Describe: 文件操作
"""

import csv
import hashlib
import json
import mimetypes
from typing import List

import requests


class FileOperation(object):

    @staticmethod
    def test_upload_file(url, file_path):
        """
        使用 requests 库上传文件到服务器
        :return:
        """
        with open(file_path, "rb") as file:
            files = {"file": ("file.txt", file)}
            response = requests.post(url, files=files)
            assert response.status_code == 200
            assert response.json()["message"] == "File uploaded successfully"

    @staticmethod
    def test_download_file(url, local_path):
        """
        下载文件并保存到本地
        :return:
        """
        response = requests.get(url)
        with open(local_path, "wb") as file:
            file.write(response.content)
        assert response.status_code == 200

    @staticmethod
    def test_compare_files(url, remote_path, local_path):
        """
        比较服务器返回的文件与本地文件的内容是否一致
        :return:
        """
        # 调用下载文件并保存到本地方法
        FileOperation.test_download_file(url, remote_path)

        with open(local_path, "r") as local_file, open(remote_path, "r") as remote_file:
            local_content = local_file.read()
            remote_content = remote_file.read()
        assert local_content == remote_content

    @staticmethod
    def test_send_csv_data(url, file_path):
        """
        读取 CSV 文件并将其中的数据作为请求参数发送给 API
        :return:
        """
        with open(file_path, newline='') as csv_file:
            reader = csv.DictReader(csv_file)
            for row in reader:
                response = requests.post(url, data=row)
                assert response.status_code == 200

    @staticmethod
    def test_send_json_data(url, file_path):
        """
        读取 JSON 文件并将其内容作为请求体发送到 API
        :return:
        """
        with open(file_path, "r") as file:
            data = json.load(file)
        response = requests.post(url, json=data)
        assert response.status_code == 200

    @staticmethod
    def test_validate_file_size(url, data_size):
        """
        下载文件并验证文件大小
        :return:
        """
        response = requests.get(url)
        file_size = len(response.content)
        assert file_size == data_size  # 假设文件大小为 1024 字节

    @staticmethod
    def test_validate_uploaded_filename(url, file_path, file_name):
        """
        上传文件并验证服务器返回的文件名
        :return:
        """
        with open(file_path, "rb") as file:
            files = {"file": (file_name, file)}
            response = requests.post(url, files=files)
            assert response.status_code == 200
            assert response.json()["filename"] == file_name

    @staticmethod
    def test_upload_multiple_files(url: str, file_paths: List[str]) -> None:
        """
        同时上传多个文件
        :return:
        """
        """
        file_paths = ["path/to/file1.txt", "path/to/file2.txt", "path/to/file3.txt"]
        """
        files = [("file", (file_path.split("/")[-1], open(file_path, "rb"))) for file_path in file_paths]
        try:
            response = requests.post(url, files=files)
            response.raise_for_status()  # 检查请求是否成功
            uploaded_files = response.json().get("uploaded_files", [])

            # 验证上传的文件数量是否与提供的文件路径数量一致
            assert len(uploaded_files) == len(files), "上传的文件数量不匹配"
            print("所有文件上传成功")
        except requests.exceptions.RequestException as e:
            print(f"请求失败: {e}")
        finally:
            # 确保所有文件都被关闭
            for _, file in files:
                file[1].close()

    @staticmethod
    def test_validate_md5_checksum(url, file_path):
        """
        上传文件并验证服务器返回的 MD5 校验码与计算出的校验码是否一致
        :return:
        """
        with open(file_path, "rb") as file:
            files = {"file": ("file.txt", file)}
            response = requests.post(url, files=files)
            assert response.status_code == 200
            md5_hash = hashlib.md5()
            with open(file_path, "rb") as file:
                chunk = file.read(8192)
                while chunk:
                    md5_hash.update(chunk)
                    chunk = file.read(8192)
            assert response.json()["md5"] == md5_hash.hexdigest()

    @staticmethod
    def test_validate_mimetype(url, file_path):
        """
        上传文件并验证服务器返回的 MIME 类型是否正确
        :return:
        """
        with open(file_path, "rb") as file:
            files = {"file": ("image.jpg", file)}
            response = requests.post(url, files=files)
            assert response.status_code == 200
            assert response.json()["mimetype"] == mimetypes.guess_type(file_path)[0]